﻿package {
	import flash.display.Sprite;
	import flash.system.System;
	import flash.ui.Keyboard;
	import flash.text.*;
	import flash.events.*;
	import util.*;
	import util.color.ColorPicker;
	import util.select.SelectList;
	import toolbar.ToolBar;
	import toolbar.IntroSquare;
	import command.RuDoCommand;
	
	public class Editor extends Sprite {
		public var toolBar:ToolBar; //工具栏
		public var mode:int; //html、ubb、可视化3种编辑模式
		
		private var inputField:TextField; //输入文本框
		private var introSquare:IntroSquare; //工具栏介绍
		private var msgBox:MsgBox; //左下角消息框
		
		private var colorPicker:ColorPicker; //拾色器
		private var fontSizeSelect:SelectList; //文字大小选择器
		private var fontFamilySelect:SelectList; //字体选择器
		
		private var textFormat:TextFormat; //当前光标所在文本的format
		private var eventParser:EventParser; //发送解析每个按钮按下后的事件
		private var content:String; //存储保存按钮保存的html内容
		
		private var rudoCommand:RuDoCommand; //存储每次操作前的html内容，用以redo和undo
		private var rudoIndex:int; //redo和rudo步骤索引
		private var inputList:Array; //输入字符后计数器和计时器
		private var inputTimer:int;

		private var biu:Boolean; //biu按钮每次按下后激活
		private var formatBlush:Boolean; //是否按下了格式刷
		private var color:Boolean; //拾色器每次按下后激活
		private var size:Boolean; //改变字体大小后激活
		private var family:Boolean; //改变字体后激活
	
		public function Editor():void {
			initView();
			init();
		}
		
		private function initView():void {
			inputField = getChildByName("input") as TextField;
			inputField.border = Config.TEXT_BORDER;
			inputField.borderColor = Config.TEXT_BORDER_COLOR;
			inputField.visible = false;
			inputField.addEventListener(MouseEvent.MOUSE_UP, onUpHandler);
			inputField.addEventListener(TextEvent.TEXT_INPUT, onInputHandler);
			inputField.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDownHandler);
			inputField.addEventListener(KeyboardEvent.KEY_UP, onKeyUpHandler);
			inputField.addEventListener(Event.ENTER_FRAME, onFrameHandler);
		}
		private function init():void {
			rudoCommand = new RuDoCommand(inputField);
			rudoIndex = inputTimer = 0;
			inputList = new Array();
			mode = Config.MODE_NORMAL;
			//初始化标量
			formatBlush = biu = color = size = family = false;
		}
		
		public function initPos(w:int, h:int):void {
			//添加toolbar
			toolBar = new ToolBar(w);
			addChild(toolBar);
			//添加introSquare
			introSquare = new IntroSquare();
			addChild(introSquare);
			//添加msgBox
			msgBox = new MsgBox();
			addChild(msgBox);
			//拾色器
			colorPicker = new ColorPicker(this);
			addChild(colorPicker);
			//大小选择
			fontSizeSelect = new SelectList(this, TextFormatAlign.RIGHT, "size");
			fontSizeSelect.addItem("8px", "8");
			fontSizeSelect.addItem("9px", "9");
			fontSizeSelect.addItem("10px", "10");
			fontSizeSelect.addItem("11px", "11");
			fontSizeSelect.addItem("12px", "12");
			fontSizeSelect.addItem("14px", "14");
			fontSizeSelect.addItem("16px", "16");
			fontSizeSelect.addItem("18px", "18");
			fontSizeSelect.addItem("24px", "24");
			fontSizeSelect.create();
			addChild(fontSizeSelect);
			//字体选择
			fontFamilySelect = new SelectList(this, TextFormatAlign.CENTER, "family");
			var chinese:RegExp = /[\u4e00-\u9fa5]/;
			var fontArray:Array = Font.enumerateFonts(true);
			for each (var font in fontArray) {
				if(chinese.test(font.fontName)) {
					fontFamilySelect.addItem(font.fontName, font.fontName);
				}
			}
			fontFamilySelect.create();
			addChild(fontFamilySelect);
			//事件分析
			eventParser = new EventParser(this);
			//设置文本框位置
			inputField.width = w - 5;
			inputField.height = h - toolBar.height - 3;
			inputField.x = 2;
			inputField.y = toolBar.height;
			inputField.visible = true;
			//设置消息框位置
			msgBox.resetY(h);
			focus();
		}
		public function resize(w:int, h:int):void {
			toolBar.resize(w);
			inputField.width = w - 5;
			inputField.height = h - toolBar.height - 3;
			inputField.y = toolBar.height;
			msgBox.resetY(h);
			focus();
		}
		public function focus():void {
			stage.focus = inputField;
		}
		public function showIntro(s:String, mx:int, my:int):void {
			introSquare.showIntro(s, mx, my);
		}
		public function hideIntro():void {
			introSquare.hideIntro();
		}
		
		private function onUpHandler(evt:MouseEvent):void {
			//点击前先检查是否有新输入没有存入命令链，设置索引
			saveInput();
			setRudoIndex();
			//隐藏拾色器，大小和字体选择
			hideColorPicker(0, false);
			hideSizeList(0, false);
			hideFamilyList("", false);
			//若有格式刷则设置
			if (formatBlush) {
				setBlush();
			}
			textFormat = null;
			//设置标量
			formatBlush = biu = color = size = family = false;
			//更新各按钮组状态
			if(mode == Config.MODE_NORMAL) {
				setBIUButton();
				setAlignButton();
			}
		}
		private function onInputHandler(event:TextEvent):void {
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//选择一段文本后再输入添加为replace命令链
			if (left != right) {
				saveInput();
				saveReplace(left, right);
			}
			//每输入一次，统计时间清零，并尝试添加输入时间侦听
			inputList.push(event.text);
			inputTimer = 0;
			if (inputField.hasEventListener(Event.ENTER_FRAME) == false) {
				inputField.addEventListener(Event.ENTER_FRAME, onFrameHandler);
			}
			//每次点击按钮并且未进行任何操作后将相应标量设为true，如此接下来输入的第一个字符进行设置format
			if (biu || color || size || family) {
				//先阻止默认输入字符事件，再将输入字符添加至光标位置，随后设置format
				event.preventDefault();
				inputField.replaceSelectedText(event.text);
				inputField.setTextFormat(textFormat, inputField.caretIndex - 1, inputField.caretIndex);
				biu = color = size = family = false;
				focus();
			}
		}
		private function onFrameHandler(evt:Event):void {
			if (++inputTimer > Config.ADD_MAX_TIMER) {
				inputTimer = 0;
				inputField.removeEventListener(Event.ENTER_FRAME, onFrameHandler);
				saveInput();
			}
		}
		private function onKeyDownHandler(evt:KeyboardEvent):void {
			//del和backspace
			if (evt.keyCode == Keyboard.DELETE) {
				//存储可能的输入命令链和选择区域链和del命令链
				saveInput();
				saveDelete();
			}
			else if (evt.keyCode == Keyboard.BACKSPACE) {
				saveInput();
				saveBackSpace();
			}
			//回车键
			if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.NUMPAD_ENTER) {
				saveInput();
			}
			//方向键
			else if (evt.keyCode == Keyboard.LEFT || evt.keyCode == Keyboard.RIGHT || evt.keyCode == Keyboard.UP || evt.keyCode == Keyboard.DOWN) {
				saveInput();
			}
		}
		private function onKeyUpHandler(evt:KeyboardEvent):void {
			//回车键
			if (evt.keyCode == Keyboard.ENTER || evt.keyCode == Keyboard.NUMPAD_ENTER) {
				setRudoIndex();
				toolBar.cancelGroup(Config.ALIGN_GROUP);
				//行尾按下BIU按钮后没进行输入，回车换行后biu清空
				if (biu) {
					toolBar.cancelGroup(Config.BIU_GROUP);
					biu = false;
				}
			}
			//方向键
			else if (evt.keyCode == Keyboard.LEFT || evt.keyCode == Keyboard.RIGHT || evt.keyCode == Keyboard.UP || evt.keyCode == Keyboard.DOWN) {
				setRudoIndex();
			}
		}
		
		private function saveInput():void {
			//有输入内容时存入add命令链，调整索引并清空输入缓存，清空format
			if (inputList.length > 0) {
				rudoCommand.addText(rudoIndex, inputList.join(""), textFormat);
				setRudoIndex();
				inputTimer = 0;
				inputList = new Array();
				textFormat = null;
			}
		}
		private function clearInput():void {
			if (inputList.length > 0) {
				inputList = new Array();
				textFormat = null;
			}
		}
		private function saveDelete():void {
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//非选择文字delete
			if(left == right) {
				//只有内容不为空切光标后有字符时才可delete
				if(inputField.caretIndex < inputField.text.length && inputField.text.length > 0) {
					var tf:TextFormat = inputField.getTextFormat(inputField.caretIndex);
					rudoCommand.delText(inputField.caretIndex, inputField.text.charAt(inputField.caretIndex), tf);
				}
			}
			//选择区域delete
			else {
				saveReplace(left, right);
			}
		}
		private function saveBackSpace():void {
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//非选择文字delete
			if(left == right) {
				//只有光标前有字符时才可backspace
				if (inputField.caretIndex > 0) {
					var tf:TextFormat = inputField.getTextFormat(inputField.caretIndex - 1);
					rudoCommand.delText(inputField.caretIndex - 1, inputField.text.charAt(inputField.caretIndex - 1), tf);
				}
			}
			//选择区域backspace
			else {
				saveReplace(left, right);
			}
		}
		private function saveReplace(left:int, right:int):void {
			//将选择文本分成区域连同format一起存入链
			var htmlLeft:int = GetBlockIndex.getHtmlLeft(inputField.htmlText, left);
			var htmlRight:int = GetBlockIndex.getHtmlRight(inputField.htmlText, right, left, htmlLeft);
			var block:Array = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right);
			var format:Array = new Array();
			for (var i:int = 0; i < block.length; i += 2) {
				format.push(inputField.getTextFormat(block[i]));
			}
			rudoCommand.addReplace(inputField.text.slice(left, right), block, format);
			setRudoIndex();
		}
		private function saveNew():void {
			if (inputField.text != "") {
				rudoCommand.newText(inputField.htmlText);
				setRudoIndex();
			}
		}
		private function saveAlign(index:Array, align:Array, newAlign:String):void {
			rudoCommand.alignParagraph(index, align, newAlign);
		}
		
		private function setRudoIndex():void {
			rudoIndex = inputField.caretIndex;
		}
		private function setBIUButton():void {
			//为空时全部取消
			if (inputField.text.length == 0) {
				toolBar.cancelGroup(Config.BIU_GROUP);
				return;
			}
			var tf:TextFormat;
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//点击则选择上一个文字，选择则本个文字
			if (left == right) {
				if (left > 0) {
					left--;
				}
				tf = inputField.getTextFormat(left);
			}
			else {
				tf = inputField.getTextFormat(left);
			}
			//检查设置粗体
			if (tf.bold == true) {
				toolBar.activeButton(Config.BIU_GROUP, Config.BOLD_ON);
			}
			else {
				toolBar.cancelButton(Config.BIU_GROUP, Config.BOLD_ON);
			}
			//检查设置斜体
			if (tf.italic == true) {
				toolBar.activeButton(Config.BIU_GROUP, Config.ITALIC_ON);
			}
			else {
				toolBar.cancelButton(Config.BIU_GROUP, Config.ITALIC_ON);
			}
			//检查设置下划线
			if (tf.underline == true) {
				toolBar.activeButton(Config.BIU_GROUP, Config.UNDERLINE_ON);
			}
			else {
				toolBar.cancelButton(Config.BIU_GROUP, Config.UNDERLINE_ON);
			}
		}
		private function setBoldItalicUnderline(bold:int, italic:int, underline:int):void {
			saveInput();
			//获得左右索引
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//没选择文本的情况下，取得当前光标坐在文本的format，然后赋值给textformat
			if (left == right) {
				//format为空时先取得上一文字的format
				if(textFormat == null) {
					textFormat = inputField.getTextFormat(left - 1);
				}
				//格式设置为true或false，其它则默认不改变
				if (bold == 1) {
					textFormat.bold = true;
				}
				else if (bold == -1) {
					textFormat.bold = false;
				}
				if (italic == 1) {
					textFormat.italic = true;
				}
				else if (italic == -1) {
					textFormat.italic = false;
				}
				if (underline == 1) {
					textFormat.underline = true;
				}
				else if (underline == -1) {
					textFormat.underline = false;
				}
				biu = true;
			}
			//选择了则逐字进行替换
			else {
				var htmlLeft:int = GetBlockIndex.getHtmlLeft(inputField.htmlText, left);
				var htmlRight:int = GetBlockIndex.getHtmlRight(inputField.htmlText, right, left, htmlLeft);
				var block:Array;
				//每个区间的原先样式和新样式和两份format拷贝做新旧替换之用
				var oldFormat = new Array();
				var newFormat = new Array();
				var tfOld:TextFormat, tfNew:TextFormat; 
				//先取得block区间数组
				if (bold == 1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "B");
				}
				else if (bold == -1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "B", false);
				}
				if (italic == 1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "I");
				}
				else if (italic == -1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "I", false);
				}
				if (underline == 1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "U");
				}
				else if (underline == -1) {
					block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right, "U", false);
				}
				//将区间数组中的每个区间设置格式
				for (var i:int = 0; i < block.length; i += 2) {
					//取两份拷贝做新旧替换之用
					tfOld = inputField.getTextFormat(block[i]);
					tfNew = inputField.getTextFormat(block[i]); 
					oldFormat.push(tfOld);
					if (bold == 1) {
						tfNew.bold = true;
					}
					else if (bold == -1) {
						tfNew.bold = false;
					}
					if (italic == 1) {
						tfNew.italic = true;
					}
					else if (italic == -1) {
						tfNew.italic = false;
					}
					if (underline == 1) {
						tfNew.underline = true;
					}
					else if (underline == -1) {
						tfNew.underline = false;
					}
					newFormat.push(tfNew);
					inputField.setTextFormat(tfNew, block[i], block[i + 1]);
				}
				//存入命令链
				rudoCommand.formatSelect(block, oldFormat, newFormat);
			}
			focus();
		}
		private function setAlignButton():void {
			if (inputField.text.length == 0) {
				toolBar.cancelGroup(Config.ALIGN_GROUP);
				return;
			}
			//检查对齐
			var left:int = GetBlockIndex.getTextLeft(inputField);
			try {
				var tf:TextFormat = inputField.getTextFormat(inputField.getFirstCharInParagraph(left));
			}
			catch (error:RangeError) {
				update();
				return;
			}
			if (tf.align == TextFormatAlign.CENTER) {
				toolBar.activeBtnInGroup(Config.ALIGN_GROUP, Config.CENTER);
			}
			else if (tf.align == TextFormatAlign.RIGHT) {
				toolBar.activeBtnInGroup(Config.ALIGN_GROUP, Config.RIGHT);
			}
			else {
				toolBar.activeBtnInGroup(Config.ALIGN_GROUP, Config.LEFT);
			}
		}
		private function setAlign(align:String):void {
			saveInput();
			//将当前选择的行设置成对齐，如果当前光标所指行为最后空行，捕捉异常并将align按钮全部取消
			try {
				//获得左右索引
				var left:int = GetBlockIndex.getTextLeft(inputField);
				var right:int = GetBlockIndex.getTextRight(inputField);
				var index:int;
				var tf:TextFormat;
				//没选择文本则设置当前行对齐
				if(left == right) {
					index = inputField.getFirstCharInParagraph(left);
					//进行一次获取行索引操作，如当前行为空则会抛出RangError被捕获
					inputField.getLineIndexOfChar(index);
					//和要设置的对齐格式相同则直接返回
					tf = inputField.getTextFormat(index, index + 1);
					if (tf.align == align) {
						return;
					}
					//先存入索引和原先对齐格式，再修改
					saveAlign([index], [tf.align], align);
					tf.align = align;
					inputField.setTextFormat(tf, index, index + 1);
				}
				//选择文本后将所有文本对应行的首字符设置对齐
				else {
					var last:int = -1;
					var iArray:Array = new Array(), aArray:Array = new Array();
					for (var i:int = left; i < right; i++) {
						index = inputField.getFirstCharInParagraph(i);
						//和上个文字处于同一段则继续
						if (index == last) {
							continue;
						}
						tf = inputField.getTextFormat(index, index + 1);
						//和要设置的对齐格式相同则直接返回
						if (tf.align == align) {
							continue;
						}
						//先存入索引和原先对齐格式
						iArray.push(index);
						aArray.push(tf.align);
						//再修改
						tf.align = align;
						inputField.setTextFormat(tf, index, index + 1);
						last = index;
					}
					saveAlign(iArray, aArray, align);
				}
			}
			catch (e:RangeError) {
				msgBox.showAlert("当前段落为空，无法设置对齐方式！");
				toolBar.cancelGroup(Config.ALIGN_GROUP);
			}
			focus();
			update();
		}
		private function setBlush():void {
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//没有选择文本范围时不做任何事
			if (left == right) {
				textFormat = null;
				formatBlush = false;
				msgBox.showMsg("没有选择任何文本应用格式刷。");
			}
			else {
				var htmlLeft:int = GetBlockIndex.getHtmlLeft(inputField.htmlText, left);
				var htmlRight:int = GetBlockIndex.getHtmlRight(inputField.htmlText, right, left, htmlLeft);
				var block:Array = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right);
				//每个区间的原先样式和新样式和两份format拷贝做新旧替换之用
				var oldFormat = new Array();
				var newFormat = new Array();
				var tfOld:TextFormat;
				//将区间数组中的每个区间设置格式
				for (var i:int = 0; i < block.length; i += 2) {
					tfOld = inputField.getTextFormat(block[i]);
					//存入新旧数组
					oldFormat.push(tfOld);
					newFormat.push(textFormat);
					inputField.setTextFormat(textFormat, block[i], block[i + 1]);
				}
				//存入命令链，前提是必须有替换
				if (oldFormat.length) {
					rudoCommand.formatSelect(block, oldFormat, newFormat);
				}
			}
		}
		
		private function copyToClipboard():Boolean {
			//先取得焦点
			focus();
			//获得左右索引
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			if (left == right) {
				msgBox.showAlert("所选内容为空。");
				return false;
			}
			//取出所选文字复制到剪贴板
			var s:String = inputField.text.slice(left, right);
			System.setClipboard(s);
			return true;
		}
		private function update():void {
			inputField.htmlText = inputField.htmlText;
		}
		
		public function sourceOn():void {
			inputField.text = inputField.htmlText;
			inputField.setTextFormat(new TextFormat(null, 12, 0, false, false, false, null, null, TextFormatAlign.LEFT));
			mode = Config.MODE_HTML;
			focus();
			toolBar.hideGroup(1);
			clearInput();
			rudoCommand.clear();
			msgBox.showAlert("切换至源代码编辑模式，请小心操作！");
		}
		public function sourceOff():void {
			inputField.htmlText = inputField.text;
			mode = Config.MODE_NORMAL;
			focus();
			toolBar.showGroup(1);
			clearInput();
			rudoCommand.clear();
			msgBox.showMsg("还原为普通编辑模式。");
		}
		public function ubbOn():void {
			if (mode == Config.MODE_HTML) {
				inputField.htmlText = inputField.text;
			}
			mode = Config.MODE_UBB;
			focus();
			toolBar.hideGroup(1);
			clearInput();
			rudoCommand.clear();
			msgBox.showAlert("暂不支持。");
		}
		public function ubbOff():void {
			mode = Config.MODE_UBB;
			focus();
			toolBar.showGroup(1);
			clearInput();
			rudoCommand.clear();
			msgBox.showAlert("暂不支持。");
		}
		public function newFile():void {
			if (inputField.text == "") {
				msgBox.showMsg("当前文件已是新文件，无需重复建立。");
			}
			else {
				saveInput();
				saveNew();
				inputField.text = "";
				msgBox.showMsg("已新建文件。");
			}
			focus();
			setRudoIndex();
		}
		public function open():void {
			if (content == null) {
				msgBox.showMsg("尚未保存文件，不能打开！");
			}
			else {
				inputField.htmlText = content;
				msgBox.showMsg("已打开文件。");
				rudoCommand.clear();
			}
		}
		public function save():void {
			if(inputField.text.length > 0) {
				content = inputField.htmlText;
				msgBox.showMsg("已保存文件内容，可供误操作后读取。");
			}
			else {
				msgBox.showAlert("文件内容为空，无法保存。");
			}
		}
		public function cut():void {
			if (copyToClipboard()) {
				inputField.replaceSelectedText("");
				msgBox.showMsg("已剪切内容。");
			}
		}
		public function copy():void {
			if (copyToClipboard()) {
				msgBox.showMsg("已复制内容。");
			}
		}
		public function paste():void {
			msgBox.showAlert("因安全限制，无法读取系统剪贴板内容，请使用鼠标右键或者快捷键<b>Ctrl</b> + <b>V</b>粘帖。");
		}
		public function blush():void {
			var left:int = GetBlockIndex.getTextLeft(inputField);
			try {
				textFormat = inputField.getTextFormat(left, left + 1);
				msgBox.showMsg("已复制样式，请选择要设置的文字范围。");
				focus();
				formatBlush = true;
			}
			catch (error:RangeError) {
				textFormat = null;
				msgBox.showAlert("当前光标所在文字样式为空！");
				focus();
				formatBlush = false;
			}
		}
		public function undo():void {
			saveInput();
			//是否成功，显示相应信息
			if (rudoCommand.undo()) {
				msgBox.showMsg("已撤销。");
			}
			else {
				msgBox.showAlert("已到达第一步，无法撤消。可保存最大步骤数目为<b>" + Config.RUDO_STEP + "</b>。");
			}
			//当内容为空后重建html，防止format缓存
			if (inputField.text.length == 0) {
				update();
			}
		}
		public function redo():void {
			//是否成功，显示相应信息
			if (rudoCommand.redo()) {
				msgBox.showMsg("已重做。");
			}
			else {
				msgBox.showAlert("已到达最后一步，无法重做。可保存最大步骤数目为<b>" + Config.RUDO_STEP + "</b>。");
			}
		}
		public function boldOn():void {
			setBoldItalicUnderline(1, 0, 0);
			msgBox.showMsg("切换为粗体。");
		}
		public function boldOff():void {
			setBoldItalicUnderline( -1, 0, 0);
			msgBox.showMsg("取消粗体。");
		}
		public function italicOn():void {
			setBoldItalicUnderline(0, 1, 0);
			msgBox.showMsg("切换为斜体。");
		}
		public function italicOff():void {
			setBoldItalicUnderline(0, -1, 0);
			msgBox.showMsg("取消斜体。");
		}
		public function underlineOn():void {
			setBoldItalicUnderline(0, 0, 1);
			msgBox.showMsg("切换为下划线。");
		}
		public function underlineOff():void {
			setBoldItalicUnderline(0, 0, -1);
			msgBox.showMsg("取消下划线。");
		}
		public function alignLeft():void {
			msgBox.showMsg("左对齐。");
			setAlign(TextFormatAlign.LEFT);
		}
		public function alignCenter():void {
			msgBox.showMsg("居中对齐。");
			setAlign(TextFormatAlign.CENTER);
		}
		public function alignRight():void {
			msgBox.showMsg("右对齐。");
			setAlign(TextFormatAlign.RIGHT);
		}
		public function showColorPicker(mx:int, my:int):void {
			toolBar.hideGroup();
			colorPicker.show(mx, my);
		}
		public function hideColorPicker(color:uint, change:Boolean = true):void {
			//计算color并显示消息
			if (change) {
				var colorString:String = color.toString(16);
				var length:int = colorString.length;
				if (length < 6) {
					for (var n:int = 0; n < 6 - length; n++) {
						colorString = "0" + colorString;
					}
				}
				//更新颜色按钮的色块
				toolBar.setColorBtn(color);
				msgBox.showMsg("已切换文字颜色为<b>#" + colorString + "</b>。");
			}
			else {
				//更新为当前光标位置颜色
				try {
					var tf:TextFormat = inputField.getTextFormat(inputField.caretIndex - 1, inputField.caretIndex);
					toolBar.setColorBtn(uint(tf.color));
				}
				catch (error:RangeError) {
					toolBar.setColorBtn();
				}
			}
			hideFontPane(color, "color", change);
		}
		public function showSizeList(mx:int, my:int):void {
			toolBar.hideGroup();
			fontSizeSelect.show(mx, my);
		}
		public function hideSizeList(size:int, change:Boolean = true):void {
			//计算size并显示消息
			if (change) {
				//更新大小按钮的文字
				toolBar.setSizeBtn(size);
				msgBox.showMsg("已切换文字大小为<b>" + size + "px</b>。");
			}
			else {
				//更新为当前光标位置大小
				try {
					var tf:TextFormat = inputField.getTextFormat(inputField.caretIndex - 1, inputField.caretIndex);
					toolBar.setSizeBtn(int(tf.size));
				}
				catch (error:RangeError) {
					toolBar.setSizeBtn();
				}
			}
			hideFontPane(size, "size", change);
		}
		public function showFamilyList(mx:int, my:int):void {
			toolBar.hideGroup();
			fontFamilySelect.show(mx, my);
		}
		public function hideFamilyList(font:String, change:Boolean = true):void {
			//计算font并显示消息
			if (change) {
				//更新大小按钮的文字
				toolBar.setFamilyBtn(font);
				msgBox.showMsg("已切换文字字体为<b>" + font + "</b>。");
			}
			else {
				//更新为当前光标位置大小
				try {
					var tf:TextFormat = inputField.getTextFormat(inputField.caretIndex - 1, inputField.caretIndex);
					toolBar.setFamilyBtn(tf.font);
				}
				catch (error:RangeError) {
					toolBar.setFamilyBtn();
				}
			}
			hideFontPane(font, "font", change);
		}
		private function hideFontPane(value:Object, type:String, change:Boolean):void {
			//隐藏font面板和intro面板
			colorPicker.visible = false;
			fontSizeSelect.visible = false;
			fontFamilySelect.visible = false;
			introSquare.visible = false;
			//显示工具栏并聚焦
			toolBar.showGroup();
			focus();
			if (!change) {
				return;
			}
			//设置格式
			var left:int = GetBlockIndex.getTextLeft(inputField);
			var right:int = GetBlockIndex.getTextRight(inputField);
			//相同时并未选择文本，设置color为true并获取tf
			if (left == right) {
				if (textFormat == null) {
					textFormat = inputField.getTextFormat(left -1);
				}
				//根据类型设置标量
				if(type == "color") {
					color = true;
					textFormat.color = uint(value);
				}
				else if (type == "size") {
					size = true;
					textFormat.size = int(value);
				}
				else {
					family = true;
					textFormat.font = String(value);
				}
			}
			//否则为替换选中文本中的颜色
			else {
				var htmlLeft:int = GetBlockIndex.getHtmlLeft(inputField.htmlText, left);
				var htmlRight:int = GetBlockIndex.getHtmlRight(inputField.htmlText, right);
				var block:Array;
				//每个区间的原先样式和新样式和两份format拷贝做新旧替换之用
				var oldFormat = new Array();
				var newFormat = new Array();
				var tfOld:TextFormat, tfNew:TextFormat;
				block = GetBlockIndex.getBIUHtmlBlock(inputField.htmlText.slice(htmlLeft, htmlRight), left, right);
				//将区间数组中的每个区间设置格式
				for (var i:int = 0; i < block.length; i += 2) {
					//取两份拷贝做新旧替换之用
					tfOld = inputField.getTextFormat(block[i]);
					tfNew = inputField.getTextFormat(block[i]);
					//替换相同时无需替换，继续循环
					if(type == "color") {
						if (uint(tfOld.color) == uint(value)) {
							continue;
						}
						else {
							tfNew.color = uint(value);
						}
					}
					else if (type == "size") {
						if (tfOld.size == int(value)) {
							continue;
						}
						else {
							tfNew.size = int(value);
						}
					}
					else {
						if (tfOld.font == String(value)) {
							continue;
						}
						else {
							tfNew.font = String(value);
						}
					}
					//存入新旧数组并设置
					oldFormat.push(tfOld);
					newFormat.push(tfNew);
					inputField.setTextFormat(tfNew, block[i], block[i + 1]);
				}
				//存入命令链，前提是必须有颜色被替换
				if (oldFormat.length) {
					rudoCommand.formatSelect(block, oldFormat, newFormat);
				}
			}
		}
	}
}